#include <iostream>
#include <future>
#include <thread>
#include <mutex>
#include <string>
#include <list>
using namespace std;

int mythread() // 线程入口函数
{
	cout << "my thread() start" << "thread is = " 
		<< this_thread::get_id() << endl;
	this_thread::sleep_for(chrono::milliseconds(5000));
	cout << "my thread() end" << endl;
	return 5;
}

void promise_test(std::promise<int>& temp, int calc)
{
	// 做一系列复杂的操作
	++calc;
	calc += 100;
	std::this_thread::sleep_for(std::chrono::milliseconds(5000));
	int result = calc;
	temp.set_value(result);
}

int main()
{

	// cout << "main" << this_thread::get_id() << endl;
	// std::future<int> result = std::async(mythread);
	// // std::launch::defer 延迟调用 没有创建新线程，是在主线程中调用函数
	// // std::launch::async 在调用async函数就开始执行，立即开始执行
	// // async() 默认使用std::launch::async
	// // 不调用get 或者wait 线程根本就不会被创建
	// // this_thread::sleep_for(std::chrono::milliseconds(6000));
	// cout << "continue" << endl;
	// int def = 0;
	// // 必须等待子线程执行结束拿到返回结果
	// // get 不拿到将来的返回值 就卡住等待取值
	// // get 只能调用一次 不能调用多次
	// cout << result.get() << endl;  // 卡在这里 等待执行完
	// // result.wait() // 等到线程返回，本身并不返回结果
	// cout << "I love china" << endl;




	// // std::packaged_task: 打包任务，把任务包装起来
	// // 是个类模板，可以把所有的可调用对象保障起来，当作线程入口函数
	// std::packaged_task<int(int)> mypt(mythread);
	// std::thread t1(std::ref(mypt), 1); // 线程直接开始执行，第二个参数作为线程
	// 									// 入口函数的参数
	// t1.join(); // 等待线程执行完毕
	// std::future<int> result = mypt.get_future();



	// std:: promise
	// 能够在某个线程中个它赋值，然后我们可以在其他线程中，把它拿出来
	// 通过promise保存一个值，在将来某个时刻我们通过把一个future绑定
	// 到这个promise上来得到绑定的值
	std::promise<int> myprom;
	std::thread t2(promise_test, std::ref(myprom), 180);
	t2.join();
	std::future<int> ful = myprom.get_future();
	auto a = ful.get();
	cout << "prom result = " << a << endl;
	return 0;
}

